package com.lifeverse.service;

import com.lifeverse.entity.BehaviorPattern;
import com.lifeverse.entity.LifeEntity;
import com.lifeverse.entity.PatternAlert;
import com.lifeverse.repository.BehaviorPatternRepository;
import com.lifeverse.repository.LifeEntityRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 模式识别服务
 * 整合各种模式识别功能的主要服务类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PatternRecognitionService {

    private final BehaviorPatternAnalyzer behaviorPatternAnalyzer;
    private final AnomalyDetectionService anomalyDetectionService;
    private final NetworkPatternRecognitionService networkPatternRecognitionService;
    private final PatternTrendAnalysisService patternTrendAnalysisService;
    private final BehaviorPatternRepository behaviorPatternRepository;
    private final LifeEntityRepository lifeEntityRepository;

    /**
     * 执行完整的模式识别分析
     */
    @Transactional
    public CompletableFuture<PatternRecognitionResult> performCompletePatternAnalysis(Long lifeEntityId, Map<String, Object> behaviorData) {
        log.info("开始为生命体 {} 执行完整的模式识别分析", lifeEntityId);
        
        return CompletableFuture.supplyAsync(() -> {
            try {
                LifeEntity lifeEntity = lifeEntityRepository.findById(lifeEntityId)
                        .orElseThrow(() -> new RuntimeException("生命体不存在: " + lifeEntityId));
                
                PatternRecognitionResult result = new PatternRecognitionResult();
                result.setLifeEntityId(lifeEntityId);
                result.setAnalysisStartTime(LocalDateTime.now());
                
                // 1. 行为模式分析
                List<BehaviorPattern> behaviorPatterns = behaviorPatternAnalyzer
                        .analyzeLifeEntityBehavior(lifeEntity, behaviorData);
                result.setBehaviorPatterns(behaviorPatterns);
                
                // 2. 异常检测
                List<PatternAlert> anomalyAlerts = anomalyDetectionService.detectAnomalies(lifeEntityId);
                result.setAnomalyAlerts(anomalyAlerts);
                
                // 3. 趋势分析
                List<PatternAlert> trendAlerts = patternTrendAnalysisService.analyzePatternTrends(lifeEntityId);
                result.setTrendAlerts(trendAlerts);
                
                // 4. 更新现有模式
                behaviorPatternAnalyzer.updateExistingPatterns(lifeEntityId);
                
                result.setAnalysisEndTime(LocalDateTime.now());
                result.setSuccess(true);
                
                log.info("生命体 {} 的模式识别分析完成，检测到 {} 个行为模式，{} 个异常预警，{} 个趋势预警", 
                        lifeEntityId, behaviorPatterns.size(), anomalyAlerts.size(), trendAlerts.size());
                
                return result;
                
            } catch (Exception e) {
                log.error("生命体 {} 的模式识别分析失败", lifeEntityId, e);
                
                PatternRecognitionResult result = new PatternRecognitionResult();
                result.setLifeEntityId(lifeEntityId);
                result.setSuccess(false);
                result.setErrorMessage(e.getMessage());
                result.setAnalysisEndTime(LocalDateTime.now());
                
                return result;
            }
        });
    }

    /**
     * 批量执行模式识别
     */
    @Async
    @Transactional
    public CompletableFuture<BatchPatternRecognitionResult> performBatchPatternAnalysis(List<Long> lifeEntityIds) {
        log.info("开始批量模式识别分析，目标生命体数量: {}", lifeEntityIds.size());
        
        return CompletableFuture.supplyAsync(() -> {
            BatchPatternRecognitionResult batchResult = new BatchPatternRecognitionResult();
            batchResult.setStartTime(LocalDateTime.now());
            batchResult.setTotalEntities(lifeEntityIds.size());
            
            List<PatternRecognitionResult> results = new ArrayList<>();
            int successCount = 0;
            int failureCount = 0;
            
            for (Long lifeEntityId : lifeEntityIds) {
                try {
                    // 为每个生命体生成模拟的行为数据
                    Map<String, Object> behaviorData = generateSimulatedBehaviorData(lifeEntityId);
                    
                    PatternRecognitionResult result = performCompletePatternAnalysis(lifeEntityId, behaviorData).get();
                    results.add(result);
                    
                    if (result.isSuccess()) {
                        successCount++;
                    } else {
                        failureCount++;
                    }
                    
                } catch (Exception e) {
                    log.error("批量分析中生命体 {} 处理失败", lifeEntityId, e);
                    failureCount++;
                }
            }
            
            batchResult.setResults(results);
            batchResult.setSuccessCount(successCount);
            batchResult.setFailureCount(failureCount);
            batchResult.setEndTime(LocalDateTime.now());
            
            log.info("批量模式识别分析完成，成功: {}，失败: {}", successCount, failureCount);
            
            return batchResult;
        });
    }

    /**
     * 定时执行网络模式识别
     */
    @Scheduled(fixedRate = 1800000) // 每30分钟执行一次
    @Transactional
    public void performScheduledNetworkPatternRecognition() {
        log.info("开始定时网络模式识别");
        
        try {
            List<BehaviorPattern> networkPatterns = networkPatternRecognitionService
                    .recognizeNetworkInteractionPatterns();
            
            log.info("定时网络模式识别完成，识别到 {} 个网络模式", networkPatterns.size());
            
        } catch (Exception e) {
            log.error("定时网络模式识别失败", e);
        }
    }

    /**
     * 定时执行异常检测
     */
    @Scheduled(fixedRate = 900000) // 每15分钟执行一次
    @Transactional
    public void performScheduledAnomalyDetection() {
        log.info("开始定时异常检测");
        
        try {
            anomalyDetectionService.detectAllAnomalies();
            log.info("定时异常检测完成");
            
        } catch (Exception e) {
            log.error("定时异常检测失败", e);
        }
    }

    /**
     * 获取模式识别统计信息
     */
    public PatternRecognitionStatistics getPatternRecognitionStatistics() {
        log.info("获取模式识别统计信息");
        
        PatternRecognitionStatistics statistics = new PatternRecognitionStatistics();
        
        try {
            LocalDateTime since = LocalDateTime.now().minus(24, ChronoUnit.HOURS);
            
            // 获取最近24小时的模式数据
            List<BehaviorPattern> recentPatterns = behaviorPatternRepository.findActivePatternsSince(since);
            
            // 按类型统计模式
            Map<String, Long> patternTypeCount = recentPatterns.stream()
                    .collect(Collectors.groupingBy(p -> p.getPatternType().name(), Collectors.counting()));
            
            // 按生命体统计
            Map<Long, Long> entityPatternCount = recentPatterns.stream()
                    .collect(Collectors.groupingBy(BehaviorPattern::getLifeEntityId, Collectors.counting()));
            
            // 计算平均置信度
            double avgConfidence = recentPatterns.stream()
                    .mapToDouble(BehaviorPattern::getConfidenceScore)
                    .average()
                    .orElse(0.0);
            
            // 计算平均异常分数
            double avgAnomalyScore = recentPatterns.stream()
                    .filter(p -> p.getAnomalyScore() != null)
                    .mapToDouble(BehaviorPattern::getAnomalyScore)
                    .average()
                    .orElse(0.0);
            
            statistics.setTotalPatterns(recentPatterns.size());
            statistics.setPatternTypeDistribution(patternTypeCount);
            statistics.setActiveEntities(entityPatternCount.size());
            statistics.setAverageConfidence(avgConfidence);
            statistics.setAverageAnomalyScore(avgAnomalyScore);
            statistics.setAnalysisPeriodHours(24);
            
            // 获取趋势预警统计
            Map<String, Object> trendStats = patternTrendAnalysisService.getTrendAlertStatistics();
            statistics.setTrendAlertStatistics(trendStats);
            
        } catch (Exception e) {
            log.error("获取模式识别统计信息时发生错误", e);
        }
        
        return statistics;
    }

    /**
     * 获取生命体的模式识别报告
     */
    public PatternRecognitionReport generatePatternReport(Long lifeEntityId) {
        log.info("生成生命体 {} 的模式识别报告", lifeEntityId);
        
        PatternRecognitionReport report = new PatternRecognitionReport();
        report.setLifeEntityId(lifeEntityId);
        report.setGeneratedAt(LocalDateTime.now());
        
        try {
            // 获取历史模式
            List<BehaviorPattern> allPatterns = behaviorPatternRepository.findByLifeEntityId(lifeEntityId);
            
            // 最近7天的模式
            LocalDateTime weekAgo = LocalDateTime.now().minus(7, ChronoUnit.DAYS);
            List<BehaviorPattern> recentPatterns = allPatterns.stream()
                    .filter(p -> p.getLastDetectedAt().isAfter(weekAgo))
                    .collect(Collectors.toList());
            
            report.setTotalPatterns(allPatterns.size());
            report.setRecentPatterns(recentPatterns.size());
            
            // 模式类型分布
            Map<String, Long> typeDistribution = allPatterns.stream()
                    .collect(Collectors.groupingBy(p -> p.getPatternType().name(), Collectors.counting()));
            report.setPatternTypeDistribution(typeDistribution);
            
            // 计算模式稳定性
            double stability = calculatePatternStability(allPatterns);
            report.setPatternStability(stability);
            
            // 计算学习进度
            double learningProgress = calculateLearningProgress(allPatterns);
            report.setLearningProgress(learningProgress);
            
            // 识别主要模式
            List<BehaviorPattern> dominantPatterns = identifyDominantPatterns(allPatterns);
            report.setDominantPatterns(dominantPatterns);
            
            // 生成建议
            List<String> recommendations = generateRecommendations(allPatterns);
            report.setRecommendations(recommendations);
            
        } catch (Exception e) {
            log.error("生成模式识别报告时发生错误", e);
            report.setErrorMessage(e.getMessage());
        }
        
        return report;
    }

    /**
     * 生成模拟的行为数据
     */
    private Map<String, Object> generateSimulatedBehaviorData(Long lifeEntityId) {
        Map<String, Object> behaviorData = new HashMap<>();
        Random random = new Random();
        
        // 模拟决策数据
        List<Map<String, Object>> decisions = new ArrayList<>();
        for (int i = 0; i < random.nextInt(10) + 5; i++) {
            Map<String, Object> decision = new HashMap<>();
            decision.put("decision_time", random.nextDouble() * 100);
            decision.put("success", random.nextBoolean());
            decision.put("complexity", random.nextDouble());
            decisions.add(decision);
        }
        behaviorData.put("decisions", decisions);
        
        // 模拟交互数据
        List<Map<String, Object>> interactions = new ArrayList<>();
        for (int i = 0; i < random.nextInt(8) + 3; i++) {
            Map<String, Object> interaction = new HashMap<>();
            interaction.put("duration", random.nextDouble() * 60);
            interaction.put("type", random.nextBoolean() ? "collaboration" : "communication");
            interactions.add(interaction);
        }
        behaviorData.put("interactions", interactions);
        
        // 模拟学习事件
        List<Map<String, Object>> learningEvents = new ArrayList<>();
        for (int i = 0; i < random.nextInt(6) + 2; i++) {
            Map<String, Object> event = new HashMap<>();
            event.put("efficiency", random.nextDouble());
            event.put("retention", random.nextDouble());
            event.put("adaptation_speed", random.nextDouble());
            learningEvents.add(event);
        }
        behaviorData.put("learning_events", learningEvents);
        
        // 模拟资源使用数据
        List<Map<String, Object>> resourceUsage = new ArrayList<>();
        for (int i = 0; i < random.nextInt(12) + 8; i++) {
            Map<String, Object> usage = new HashMap<>();
            usage.put("efficiency", random.nextDouble());
            usage.put("usage_amount", random.nextDouble() * 100);
            usage.put("waste_ratio", random.nextDouble() * 0.3);
            resourceUsage.add(usage);
        }
        behaviorData.put("resource_usage", resourceUsage);
        
        return behaviorData;
    }

    /**
     * 计算模式稳定性
     */
    private double calculatePatternStability(List<BehaviorPattern> patterns) {
        if (patterns.isEmpty()) return 0.0;
        
        // 基于模式的持续时间和频率计算稳定性
        double avgDuration = patterns.stream()
                .filter(p -> p.getDurationMinutes() != null)
                .mapToDouble(p -> p.getDurationMinutes().doubleValue())
                .average()
                .orElse(0.0);
        
        double avgFrequency = patterns.stream()
                .mapToDouble(BehaviorPattern::getFrequency)
                .average()
                .orElse(0.0);
        
        // 简化的稳定性计算
        return Math.min((avgDuration / 1440.0 + avgFrequency / 100.0) / 2.0, 1.0);
    }

    /**
     * 计算学习进度
     */
    private double calculateLearningProgress(List<BehaviorPattern> patterns) {
        if (patterns.isEmpty()) return 0.0;
        
        // 基于置信度的提升计算学习进度
        patterns.sort(Comparator.comparing(BehaviorPattern::getFirstDetectedAt));
        
        if (patterns.size() < 2) return 0.5;
        
        double initialConfidence = patterns.subList(0, Math.min(3, patterns.size())).stream()
                .mapToDouble(BehaviorPattern::getConfidenceScore)
                .average()
                .orElse(0.0);
        
        double recentConfidence = patterns.subList(Math.max(0, patterns.size() - 3), patterns.size()).stream()
                .mapToDouble(BehaviorPattern::getConfidenceScore)
                .average()
                .orElse(0.0);
        
        return Math.min(recentConfidence / Math.max(initialConfidence, 0.1), 2.0) / 2.0;
    }

    /**
     * 识别主要模式
     */
    private List<BehaviorPattern> identifyDominantPatterns(List<BehaviorPattern> patterns) {
        return patterns.stream()
                .filter(p -> p.getConfidenceScore() > 0.8 && p.getFrequency() > 5)
                .sorted(Comparator.comparing(BehaviorPattern::getConfidenceScore).reversed())
                .limit(5)
                .collect(Collectors.toList());
    }

    /**
     * 生成建议
     */
    private List<String> generateRecommendations(List<BehaviorPattern> patterns) {
        List<String> recommendations = new ArrayList<>();
        
        if (patterns.isEmpty()) {
            recommendations.add("增加生命体的活动和交互以建立行为模式");
            return recommendations;
        }
        
        double avgConfidence = patterns.stream()
                .mapToDouble(BehaviorPattern::getConfidenceScore)
                .average()
                .orElse(0.0);
        
        if (avgConfidence < 0.6) {
            recommendations.add("提高行为模式的一致性以增加置信度");
        }
        
        long learningPatterns = patterns.stream()
                .filter(p -> p.getPatternType().name().equals("LEARNING"))
                .count();
        
        if (learningPatterns == 0) {
            recommendations.add("增加学习活动以促进智能发展");
        }
        
        long anomalousPatterns = patterns.stream()
                .filter(p -> p.getAnomalyScore() != null && p.getAnomalyScore() > 0.7)
                .count();
        
        if (anomalousPatterns > patterns.size() * 0.2) {
            recommendations.add("关注异常行为模式，可能需要调整参数");
        }
        
        return recommendations;
    }

    // 结果类定义
    public static class PatternRecognitionResult {
        private Long lifeEntityId;
        private boolean success;
        private String errorMessage;
        private LocalDateTime analysisStartTime;
        private LocalDateTime analysisEndTime;
        private List<BehaviorPattern> behaviorPatterns = new ArrayList<>();
        private List<PatternAlert> anomalyAlerts = new ArrayList<>();
        private List<PatternAlert> trendAlerts = new ArrayList<>();

        // getters and setters
        public Long getLifeEntityId() { return lifeEntityId; }
        public void setLifeEntityId(Long lifeEntityId) { this.lifeEntityId = lifeEntityId; }
        public boolean isSuccess() { return success; }
        public void setSuccess(boolean success) { this.success = success; }
        public String getErrorMessage() { return errorMessage; }
        public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
        public LocalDateTime getAnalysisStartTime() { return analysisStartTime; }
        public void setAnalysisStartTime(LocalDateTime analysisStartTime) { this.analysisStartTime = analysisStartTime; }
        public LocalDateTime getAnalysisEndTime() { return analysisEndTime; }
        public void setAnalysisEndTime(LocalDateTime analysisEndTime) { this.analysisEndTime = analysisEndTime; }
        public List<BehaviorPattern> getBehaviorPatterns() { return behaviorPatterns; }
        public void setBehaviorPatterns(List<BehaviorPattern> behaviorPatterns) { this.behaviorPatterns = behaviorPatterns; }
        public List<PatternAlert> getAnomalyAlerts() { return anomalyAlerts; }
        public void setAnomalyAlerts(List<PatternAlert> anomalyAlerts) { this.anomalyAlerts = anomalyAlerts; }
        public List<PatternAlert> getTrendAlerts() { return trendAlerts; }
        public void setTrendAlerts(List<PatternAlert> trendAlerts) { this.trendAlerts = trendAlerts; }
    }

    public static class BatchPatternRecognitionResult {
        private LocalDateTime startTime;
        private LocalDateTime endTime;
        private int totalEntities;
        private int successCount;
        private int failureCount;
        private List<PatternRecognitionResult> results = new ArrayList<>();

        // getters and setters
        public LocalDateTime getStartTime() { return startTime; }
        public void setStartTime(LocalDateTime startTime) { this.startTime = startTime; }
        public LocalDateTime getEndTime() { return endTime; }
        public void setEndTime(LocalDateTime endTime) { this.endTime = endTime; }
        public int getTotalEntities() { return totalEntities; }
        public void setTotalEntities(int totalEntities) { this.totalEntities = totalEntities; }
        public int getSuccessCount() { return successCount; }
        public void setSuccessCount(int successCount) { this.successCount = successCount; }
        public int getFailureCount() { return failureCount; }
        public void setFailureCount(int failureCount) { this.failureCount = failureCount; }
        public List<PatternRecognitionResult> getResults() { return results; }
        public void setResults(List<PatternRecognitionResult> results) { this.results = results; }
    }

    public static class PatternRecognitionStatistics {
        private int totalPatterns;
        private Map<String, Long> patternTypeDistribution = new HashMap<>();
        private int activeEntities;
        private double averageConfidence;
        private double averageAnomalyScore;
        private int analysisPeriodHours;
        private Map<String, Object> trendAlertStatistics = new HashMap<>();

        // getters and setters
        public int getTotalPatterns() { return totalPatterns; }
        public void setTotalPatterns(int totalPatterns) { this.totalPatterns = totalPatterns; }
        public Map<String, Long> getPatternTypeDistribution() { return patternTypeDistribution; }
        public void setPatternTypeDistribution(Map<String, Long> patternTypeDistribution) { this.patternTypeDistribution = patternTypeDistribution; }
        public int getActiveEntities() { return activeEntities; }
        public void setActiveEntities(int activeEntities) { this.activeEntities = activeEntities; }
        public double getAverageConfidence() { return averageConfidence; }
        public void setAverageConfidence(double averageConfidence) { this.averageConfidence = averageConfidence; }
        public double getAverageAnomalyScore() { return averageAnomalyScore; }
        public void setAverageAnomalyScore(double averageAnomalyScore) { this.averageAnomalyScore = averageAnomalyScore; }
        public int getAnalysisPeriodHours() { return analysisPeriodHours; }
        public void setAnalysisPeriodHours(int analysisPeriodHours) { this.analysisPeriodHours = analysisPeriodHours; }
        public Map<String, Object> getTrendAlertStatistics() { return trendAlertStatistics; }
        public void setTrendAlertStatistics(Map<String, Object> trendAlertStatistics) { this.trendAlertStatistics = trendAlertStatistics; }
    }

    public static class PatternRecognitionReport {
        private Long lifeEntityId;
        private LocalDateTime generatedAt;
        private int totalPatterns;
        private int recentPatterns;
        private Map<String, Long> patternTypeDistribution = new HashMap<>();
        private double patternStability;
        private double learningProgress;
        private List<BehaviorPattern> dominantPatterns = new ArrayList<>();
        private List<String> recommendations = new ArrayList<>();
        private String errorMessage;

        // getters and setters
        public Long getLifeEntityId() { return lifeEntityId; }
        public void setLifeEntityId(Long lifeEntityId) { this.lifeEntityId = lifeEntityId; }
        public LocalDateTime getGeneratedAt() { return generatedAt; }
        public void setGeneratedAt(LocalDateTime generatedAt) { this.generatedAt = generatedAt; }
        public int getTotalPatterns() { return totalPatterns; }
        public void setTotalPatterns(int totalPatterns) { this.totalPatterns = totalPatterns; }
        public int getRecentPatterns() { return recentPatterns; }
        public void setRecentPatterns(int recentPatterns) { this.recentPatterns = recentPatterns; }
        public Map<String, Long> getPatternTypeDistribution() { return patternTypeDistribution; }
        public void setPatternTypeDistribution(Map<String, Long> patternTypeDistribution) { this.patternTypeDistribution = patternTypeDistribution; }
        public double getPatternStability() { return patternStability; }
        public void setPatternStability(double patternStability) { this.patternStability = patternStability; }
        public double getLearningProgress() { return learningProgress; }
        public void setLearningProgress(double learningProgress) { this.learningProgress = learningProgress; }
        public List<BehaviorPattern> getDominantPatterns() { return dominantPatterns; }
        public void setDominantPatterns(List<BehaviorPattern> dominantPatterns) { this.dominantPatterns = dominantPatterns; }
        public List<String> getRecommendations() { return recommendations; }
        public void setRecommendations(List<String> recommendations) { this.recommendations = recommendations; }
        public String getErrorMessage() { return errorMessage; }
        public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
    }
}